package com.kexio.file.controller;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.kexio.auth.annotation.Audit;
import com.kexio.auth.annotation.PublicApi;
import com.kexio.auth.annotation.RequiresPermission;
import com.kexio.common.dto.Result;
import com.kexio.file.config.FileStorageConfiguration;
import com.kexio.file.entity.FileStorageConfig;
import com.kexio.file.service.FileStorageConfigService;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;

/**
 * 文件存储配置管理控制器
 * 支持多种存储配置的动态管理
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
@Tag(name = "文件存储配置管理", description = "文件存储配置的增删改查、启用禁用、默认设置等功能")
@RestController
@RequestMapping("/file/storage-config")
public class FileStorageConfigController {

    @Autowired
    private FileStorageConfigService fileStorageConfigService;
    
    @Autowired
    private FileStorageConfiguration fileStorageConfiguration;

    /**
     * 分页查询存储配置
     */
    @Operation(summary = "分页查询存储配置", description = "根据条件分页查询存储配置列表")
    @GetMapping("/page")
    @RequiresPermission("file:config:view")
    @Audit(value = "查询存储配置分页", module = "file")
    public Result<IPage<FileStorageConfig>> pageConfigs(
            @Parameter(description = "当前页码") @RequestParam(defaultValue = "1") Long current,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "10") Long size,
            @Parameter(description = "配置名称") @RequestParam(required = false) String configName,
            @Parameter(description = "存储类型") @RequestParam(required = false) String configType,
            @Parameter(description = "启用状态") @RequestParam(required = false) Boolean enabled) {
        
        try {
            IPage<FileStorageConfig> result = fileStorageConfigService.pageConfigs(current, size, configName, configType, enabled);
            return Result.success(result);
        } catch (Exception e) {
            // 添加详细的错误信息用于调试
            return Result.error("查询配置失败: " + e.getMessage() + ", 原因: " + (e.getCause() != null ? e.getCause().getMessage() : "未知"));
        }
    }
    
    /**
     * 测试接口 - 用于验证控制器是否正常工作
     */
    @Operation(summary = "测试接口", description = "测试控制器是否正常工作")
    @GetMapping("/test")
    @Audit(value = "文件存储配置-健康测试", module = "file")
    public Result<String> test() {
        return Result.success("FileStorageConfigController 正常工作！服务状态: " + 
                              (fileStorageConfigService != null ? "已注入" : "未注入"));
    }

    /**
     * 获取所有启用的配置列表
     */
    @Operation(summary = "获取启用的配置列表", description = "获取所有启用状态的存储配置")
    @GetMapping("/enabled")
    @RequiresPermission("file:config:view")
    @Audit(value = "查询启用的存储配置", module = "file")
    public Result<List<FileStorageConfig>> listEnabledConfigs() {
        List<FileStorageConfig> configs = fileStorageConfigService.listEnabledConfigs();
        return Result.success(configs);
    }

    /**
     * 根据存储类型获取配置列表
     */
    @Operation(summary = "根据类型查询配置", description = "根据存储类型获取配置列表")
    @GetMapping("/type/{configType}")
    @RequiresPermission("file:config:view")
    @Audit(value = "按类型查询存储配置", module = "file")
    public Result<List<FileStorageConfig>> listConfigsByType(
            @Parameter(description = "存储类型") @PathVariable String configType) {
        List<FileStorageConfig> configs = fileStorageConfigService.listConfigsByType(configType);
        return Result.success(configs);
    }

    /**
     * 获取默认存储配置
     */
    @Operation(summary = "获取默认配置", description = "获取当前默认的存储配置")
    @GetMapping("/default")
    @RequiresPermission("file:config:view")
    @Audit(value = "获取默认存储配置", module = "file")
    public Result<FileStorageConfig> getDefaultConfig() {
        FileStorageConfig config = fileStorageConfigService.getDefaultConfig();
        return Result.success(config);
    }

    /**
     * 根据ID获取配置详情
     */
    @Operation(summary = "获取配置详情", description = "根据配置ID获取详细信息")
    @GetMapping("/{configId}")
    @RequiresPermission("file:config:view")
    @Audit(value = "获取存储配置详情", module = "file")
    public Result<FileStorageConfig> getConfig(
            @Parameter(description = "配置ID") @PathVariable String configId) {
        FileStorageConfig config = fileStorageConfigService.getById(configId);
        if (config == null) {
            return Result.error("配置不存在");
        }
        return Result.success(config);
    }

    /**
     * 创建存储配置
     */
    @Operation(summary = "创建存储配置", description = "创建新的文件存储配置")
    @PostMapping
    @RequiresPermission("file:config:create")
    @Audit(value = "创建存储配置", module = "file")
    public Result<FileStorageConfig> createConfig(@RequestBody FileStorageConfig config) {
        try {
            FileStorageConfig result = fileStorageConfigService.createConfig(config);
            return Result.success(result);
        } catch (Exception e) {
            return Result.error("创建配置失败: " + e.getMessage());
        }
    }

    /**
     * 更新存储配置
     */
    @Operation(summary = "更新存储配置", description = "更新指定的文件存储配置")
    @PutMapping("/{configId}")
    @RequiresPermission("file:config:update")
    @Audit(value = "更新存储配置", module = "file")
    public Result<FileStorageConfig> updateConfig(
            @Parameter(description = "配置ID") @PathVariable String configId,
            @RequestBody FileStorageConfig config) {
        try {
            config.setId(configId);
            FileStorageConfig result = fileStorageConfigService.updateConfig(config);
            return Result.success(result);
        } catch (Exception e) {
            return Result.error("更新配置失败: " + e.getMessage());
        }
    }

    /**
     * 删除存储配置
     */
    @Operation(summary = "删除存储配置", description = "删除指定的文件存储配置")
    @DeleteMapping("/{configId}")
    @RequiresPermission("file:config:delete")
    @Audit(value = "删除存储配置", module = "file")
    public Result<Void> deleteConfig(
            @Parameter(description = "配置ID") @PathVariable String configId) {
        try {
            boolean result = fileStorageConfigService.deleteConfig(configId);
            if (result) {
                return Result.success();
            } else {
                return Result.error("删除配置失败");
            }
        } catch (Exception e) {
            return Result.error("删除配置失败: " + e.getMessage());
        }
    }

    /**
     * 批量删除存储配置
     */
    @Operation(summary = "批量删除配置", description = "批量删除指定的存储配置")
    @DeleteMapping("/batch")
    @RequiresPermission("file:config:delete")
    @Audit(value = "批量删除存储配置", module = "file")
    public Result<Map<String, Object>> batchDeleteConfigs(@RequestBody List<String> configIds) {
        try {
            int deletedCount = fileStorageConfigService.batchDeleteConfigs(configIds);
            return Result.success(Map.of("deletedCount", deletedCount));
        } catch (Exception e) {
            return Result.error("批量删除失败: " + e.getMessage());
        }
    }

    /**
     * 设置默认配置
     */
    @Operation(summary = "设置默认配置", description = "将指定配置设置为默认存储配置")
    @PutMapping("/{configId}/default")
    @RequiresPermission("file:config:update")
    @Audit(value = "设置默认存储配置", module = "file")
    public Result<Void> setDefaultConfig(
            @Parameter(description = "配置ID") @PathVariable String configId) {
        try {
            boolean result = fileStorageConfigService.setDefaultConfig(configId);
            if (result) {
                return Result.success();
            } else {
                return Result.error("设置默认配置失败");
            }
        } catch (Exception e) {
            return Result.error("设置默认配置失败: " + e.getMessage());
        }
    }

    /**
     * 启用/禁用配置
     */
    @Operation(summary = "切换配置状态", description = "启用或禁用指定的存储配置")
    @PutMapping("/{configId}/toggle")
    @RequiresPermission("file:config:update")
    @Audit(value = "切换存储配置状态", module = "file")
    public Result<Void> toggleConfigStatus(
            @Parameter(description = "配置ID") @PathVariable String configId,
            @Parameter(description = "启用状态") @RequestParam Boolean enabled) {
        try {
            boolean result = fileStorageConfigService.toggleConfigStatus(configId, enabled);
            if (result) {
                return Result.success();
            } else {
                return Result.error("更新配置状态失败");
            }
        } catch (Exception e) {
            return Result.error("更新配置状态失败: " + e.getMessage());
        }
    }

    /**
     * 批量更新排序
     */
    @Operation(summary = "更新排序", description = "批量更新配置的排序顺序")
    @PutMapping("/sort")
    @RequiresPermission("file:config:update")
    @Audit(value = "更新存储配置排序", module = "file")
    public Result<Void> updateSortOrder(@RequestBody List<FileStorageConfig> configs) {
        try {
            boolean result = fileStorageConfigService.updateSortOrder(configs);
            if (result) {
                return Result.success();
            } else {
                return Result.error("更新排序失败");
            }
        } catch (Exception e) {
            return Result.error("更新排序失败: " + e.getMessage());
        }
    }

    /**
     * 测试配置连接
     */
    @Operation(summary = "测试连接", description = "测试存储配置的连接是否正常")
    @PostMapping("/test")
    @RequiresPermission("file:config:view")
    @Audit(value = "测试存储配置连接", module = "file")
    public Result<Map<String, Object>> testConnection(@RequestBody FileStorageConfig config) {
        Map<String, Object> result = fileStorageConfigService.testConnection(config);
        return Result.success(result);
    }

    /**
     * 验证配置参数
     */
    @Operation(summary = "验证配置参数", description = "验证存储配置参数的有效性")
    @PostMapping("/validate")
    @RequiresPermission("file:config:view")
    @Audit(value = "验证存储配置参数", module = "file")
    public Result<Map<String, Object>> validateConfig(
            @Parameter(description = "存储类型") @RequestParam String configType,
            @Parameter(description = "配置参数JSON") @RequestParam String configParams) {
        Map<String, Object> result = fileStorageConfigService.validateConfig(configType, configParams);
        return Result.success(result);
    }

    /**
     * 复制配置
     */
    @Operation(summary = "复制配置", description = "复制现有的存储配置")
    @PostMapping("/{configId}/copy")
    @RequiresPermission("file:config:create")
    @Audit(value = "复制存储配置", module = "file")
    public Result<FileStorageConfig> copyConfig(
            @Parameter(description = "源配置ID") @PathVariable String configId,
            @Parameter(description = "新配置名称") @RequestParam String newConfigName) {
        try {
            FileStorageConfig result = fileStorageConfigService.copyConfig(configId, newConfigName);
            return Result.success(result);
        } catch (Exception e) {
            return Result.error("复制配置失败: " + e.getMessage());
        }
    }

    /**
     * 获取存储类型选项
     */
    @Operation(summary = "获取存储类型选项", description = "获取支持的存储类型列表")
    @GetMapping("/storage-types")
    @RequiresPermission("file:config:view")
    @Audit(value = "获取存储类型选项", module = "file")
    public Result<List<Map<String, Object>>> getStorageTypeOptions() {
        List<Map<String, Object>> options = fileStorageConfigService.getStorageTypeOptions();
        return Result.success(options);
    }

    /**
     * 获取配置参数模板
     */
    @Operation(summary = "获取参数模板", description = "根据存储类型获取配置参数模板")
    @GetMapping("/template/{configType}")
    @RequiresPermission("file:config:view")
    @Audit(value = "获取存储配置参数模板", module = "file")
    public Result<Map<String, Object>> getConfigTemplate(
            @Parameter(description = "存储类型") @PathVariable String configType) {
        Map<String, Object> template = fileStorageConfigService.getConfigTemplate(configType);
        return Result.success(template);
    }

    /**
     * 获取使用统计
     */
    @Operation(summary = "获取使用统计", description = "获取各存储配置的使用统计信息")
    @GetMapping("/stats")
    @RequiresPermission("file:config:view")
    @Audit(value = "获取存储配置使用统计", module = "file")
    public Result<List<Map<String, Object>>> getUsageStats() {
        List<Map<String, Object>> stats = fileStorageConfigService.getUsageStats();
        return Result.success(stats);
    }

    /**
     * 导出配置
     */
    @Operation(summary = "导出配置", description = "导出指定的存储配置")
    @PostMapping("/export")
    @RequiresPermission("file:config:export")
    @Audit(value = "导出存储配置", module = "file")
    public Result<List<Map<String, Object>>> exportConfigs(@RequestBody List<String> configIds) {
        try {
            List<Map<String, Object>> result = fileStorageConfigService.exportConfigs(configIds);
            return Result.success(result);
        } catch (Exception e) {
            return Result.error("导出配置失败: " + e.getMessage());
        }
    }

    /**
     * 导入配置
     */
    @Operation(summary = "导入配置", description = "导入存储配置数据")
    @PostMapping("/import")
    @RequiresPermission("file:config:import")
    @Audit(value = "导入存储配置", module = "file")
    public Result<Map<String, Object>> importConfigs(@RequestBody List<Map<String, Object>> configData) {
        try {
            Map<String, Object> result = fileStorageConfigService.importConfigs(configData);
            return Result.success(result);
        } catch (Exception e) {
            return Result.error("导入配置失败: " + e.getMessage());
        }
    }

    /**
     * 检查配置名称唯一性
     */
    @Operation(summary = "检查名称唯一性", description = "检查配置名称是否已存在")
    @GetMapping("/check-name")
    @RequiresPermission("file:config:view")
    @Audit(value = "检查存储配置名称唯一性", module = "file")
    public Result<Map<String, Object>> checkConfigName(
            @Parameter(description = "配置名称") @RequestParam String configName,
            @Parameter(description = "排除的配置ID") @RequestParam(required = false) String excludeId) {
        boolean unique = fileStorageConfigService.isConfigNameUnique(configName, excludeId);
        return Result.success(Map.of("unique", unique));
    }
    
    /**
     * 手动重新加载配置（配置热更新）
     */
    @Operation(summary = "重新加载配置", description = "手动触发配置热更新，使最新的默认配置立即生效")
    @PostMapping("/reload")
    @RequiresPermission("file:config:update")
    @Audit(value = "重新加载存储配置", module = "file")
    public Result<Map<String, Object>> reloadConfiguration() {
        try {
            fileStorageConfiguration.reloadStorageConfiguration();
            Map<String, Object> currentInfo = fileStorageConfiguration.getCurrentStorageInfo();
            Result<Map<String, Object>> result = Result.success(currentInfo);
            result.setMessage("配置热更新成功，新配置已生效");
            return result;
        } catch (Exception e) {
            return Result.error("配置重新加载失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取当前生效的配置信息
     */
    @Operation(summary = "获取当前配置", description = "获取当前系统中实际生效的存储配置信息")
    @GetMapping("/current")
    @RequiresPermission("file:config:view")
    @Audit(value = "获取当前存储配置信息", module = "file")
    public Result<Map<String, Object>> getCurrentConfig() {
        Map<String, Object> currentInfo = fileStorageConfiguration.getCurrentStorageInfo();
        return Result.success(currentInfo);
    }
    
    /**
     * 调试接口：获取当前生效的配置信息（无需认证）
     */
    @Operation(summary = "调试获取当前配置", description = "调试用：获取当前系统中实际生效的存储配置信息（无需认证）")
    @GetMapping("/debug/current")
    @PublicApi(description = "调试获取当前存储配置")
    public Result<Map<String, Object>> debugGetCurrentConfig() {
        Map<String, Object> currentInfo = fileStorageConfiguration.getCurrentStorageInfo();
        
        // 添加更多调试信息
        try {
            FileStorageConfig defaultConfig = fileStorageConfigService.getDefaultConfig();
            currentInfo.put("databaseDefaultConfig", defaultConfig);
        } catch (Exception e) {
            currentInfo.put("databaseDefaultConfigError", e.getMessage());
        }
        
        currentInfo.put("debugMessage", "此接口用于调试存储配置问题");
        return Result.success(currentInfo);
    }
}
